package core;

import java.util.Stack;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Screen;

import protocol.Request;
import protocol.Response;
import protocol.changePassword.ChangePasswordRequest;
import protocol.changePassword.ChangePasswordResponse;
import protocol.login.LoginRequest;
import protocol.login.LoginResponse;
import protocol.vendasFuncionario.VendasFuncionarioRequest;
import protocol.vendasFuncionario.VendasFuncionarioResponse;
import protocol.vendasProduto.VendasProdutoRequest;
import protocol.vendasProduto.VendasProdutoResponse;
import screens.MenuList;
import screens.VendasFuncionarioCanvas;
import screens.VendasProdutoCanvas;

public class UIController {

	private Display display;
	private RVMMidlet midlet;

	private Stack screens;

	private Request request;
	private Response response;
	private Connection connection;
	private Dispatcher dispatcher;

	private static UIController instance;
	private static Screen telaPrincipal;

	private UIController(RVMMidlet midlet) {
		this.midlet = midlet;
		this.display = Display.getDisplay(midlet);
		this.screens = new Stack();

		this.connection = new Connection();
		this.connection.start();

		this.dispatcher = new Dispatcher();
		this.dispatcher.start();
	}

	public static UIController createInstance(RVMMidlet midlet) {
		if (instance == null) {
			instance = new UIController(midlet);
			telaPrincipal = MenuList.getInstance();
		}
		return instance;
	}

	public static UIController getInstance() throws Exception {
		if (instance == null) {
			throw new Exception("Instancia não criada");
		}
		return instance;
	}

	public void login(String login, String senha) {
		if (login == null || login.length() <= 0) {
			System.out.println("#UIController: falta o login");
		} else if (senha == null || senha.length() <= 0) {
			System.out.println("#UIController: falta a senha");
		} else {// ir ao servidor e validar login
			this.request = new LoginRequest(login, senha);
			execute();
			// encaminha para tela de menu
		}
	}

	public void doChangePassword(String login, String antigaSenha,
			String novaSenha, String confirmacao) {
		if ((!login.equals("")) && (!antigaSenha.equals("")) && (!novaSenha.equals(""))
				&& (novaSenha.equals(confirmacao))) {
			this.request = new ChangePasswordRequest(login, antigaSenha,
					novaSenha);
			execute();
		} else {
			System.out.println("Problemas com as credenciais informadas");
		}
	}

	public void doVendasFuncionario(int mes, String ano) {
		this.request = new VendasFuncionarioRequest(mes, ano);
		execute();
	}

	public void doVendasProduto(int mes, String ano) {
		this.request = new VendasProdutoRequest(mes, ano);
		execute();
	}

	private void execute() {
		synchronized (dispatcher) {
			dispatcher.notifyAll();
		}
	}

	public void sair() {
		this.midlet.destroyApp(true);
		this.midlet.notifyDestroyed();
	}

	public void setCurrent(Displayable displayable) {
		this.screens.push(displayable);
		this.display.setCurrent(displayable);
	}

	public void voltar() {
		this.display.setCurrent(telaPrincipal);
	}

	class Dispatcher extends Thread {

		private boolean running = true;

		public void run() {

			while (running) {
				synchronized (this) {
					try {
						this.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				response = performConnection();
				if (response instanceof LoginResponse) {
					if (response.getResponse().equals("OK")) {
						setCurrent(MenuList.getInstance());
					} else {
						Alert alert = new Alert("ERRO!");
						alert.setString("Falha de login");
						alert.setTimeout(2000);
						setCurrent(alert);
					}
				} else if (response instanceof VendasFuncionarioResponse) {
					VendasFuncionarioCanvas.getInstance().setColuna1Label(
							((VendasFuncionarioResponse) response)
									.getColuna1Label());
					VendasFuncionarioCanvas.getInstance().setColuna2Label(
							((VendasFuncionarioResponse) response)
									.getColuna2Label());
					VendasFuncionarioCanvas.getInstance().setColuna3Label(
							((VendasFuncionarioResponse) response)
									.getColuna3Label());
					VendasFuncionarioCanvas.getInstance()
							.setColuna1(
									((VendasFuncionarioResponse) response)
											.getColuna1());
					VendasFuncionarioCanvas.getInstance()
							.setColuna2(
									((VendasFuncionarioResponse) response)
											.getColuna2());
					VendasFuncionarioCanvas.getInstance()
							.setColuna3(
									((VendasFuncionarioResponse) response)
											.getColuna3());
					setCurrent(VendasFuncionarioCanvas.getInstance());
				} else if (response instanceof VendasProdutoResponse) {
					VendasProdutoCanvas.getInstance().setColuna1Label(
							((VendasProdutoResponse) response)
									.getColuna1Label());
					VendasProdutoCanvas.getInstance().setColuna2Label(
							((VendasProdutoResponse) response)
									.getColuna2Label());
					VendasProdutoCanvas.getInstance().setColuna3Label(
							((VendasProdutoResponse) response)
									.getColuna3Label());
					VendasProdutoCanvas.getInstance().setColuna1(
							((VendasProdutoResponse) response).getColuna1());
					VendasProdutoCanvas.getInstance().setColuna2(
							((VendasProdutoResponse) response).getColuna2());
					VendasProdutoCanvas.getInstance().setColuna3(
							((VendasProdutoResponse) response).getColuna3());
					setCurrent(VendasProdutoCanvas.getInstance());
				} else if (response instanceof ChangePasswordResponse) {
					if (response.getResponse().equals("OK")) {
						setCurrent(MenuList.getInstance());
					} else {
						Alert alert = new Alert("ERRO!");
						alert.setString("Falha de login");
						alert.setTimeout(2000);
						setCurrent(alert);
					}
				}
			}
		}

		private Response performConnection() {
			synchronized (connection) {
				connection.setRequest(request);
				connection.notifyAll();
				try {
					connection.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			return connection.getResponse();
		}
	}

}
